package com.carbon.assets.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carbon.assets.common.enums.ProjectStatus;
import com.carbon.assets.entity.CarbonProject;
import com.carbon.assets.entity.CarbonProjectContent;
import com.carbon.assets.entity.CarbonResourceFile;
import com.carbon.assets.mapper.CarbonMethodologyMapper;
import com.carbon.assets.mapper.CarbonProjectMapper;
import com.carbon.assets.mapper.DictMapper;
import com.carbon.assets.param.*;
import com.carbon.assets.service.CarbonProjectService;
import com.carbon.assets.service.CarbonResourceFileService;
import com.carbon.assets.util.ProjectAddUtil;
import com.carbon.assets.vo.CarbonDetectionDataVo;
import com.carbon.assets.vo.CarbonProjectListVo;
import com.carbon.assets.vo.CarbonProjectQueryVo;
import com.carbon.common.enums.ExpCodeEnum;
import com.carbon.common.exception.CommonBizException;
import com.carbon.common.service.BaseServiceImpl;
import com.carbon.common.api.Paging;
import com.carbon.domain.common.ApiResult;
import com.carbon.domain.common.constant.RocketDelayLevelConstant;
import com.carbon.domain.common.constant.RocketMqName;
import com.carbon.domain.mq.entity.ProjectApproval;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;


/**
 * <p>
 * 碳减排项目 服务实现类
 * </p>

 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class CarbonProjectServiceImpl extends BaseServiceImpl<CarbonProjectMapper, CarbonProject> implements CarbonProjectService {

    @Resource
    private CarbonProjectMapper carbonProjectMapper;

    @Resource
    private CarbonMethodologyMapper carbonMethodologyMapper;
    @Autowired
    private CarbonResourceFileService carbonResourceFileService;
    @Resource
    private RocketMQTemplate mqTemplate;

    @Autowired
    DictMapper dictMapper;


    @Override
    public Boolean delDataSubmissionPage(String id) {
        return carbonProjectMapper.delDataSubmissionPage(id);
    }

    @Override
    public List<String> updateDataSubmissionPage(String id) {
        return carbonProjectMapper.updateDataSubmissionPage(id);
    }

    @Override
    public List<CarbonDetectionDataVo> getDataSubmissionPageById(String id) {

        return carbonProjectMapper.getDataSubmissionPageById(id);
    }

    /**
     * 向数据库插入提交信息
     *
     * 本方法首先生成一个特定格式的因子代码(factorCode)，并将其设置到提交参数对象中
     * 然后使用设置后的参数对象，分别向因子表和项目表插入提交信息
     *
     * @param param 提交参数对象，包含要插入数据库的提交信息
     * @return 返回插入操作的结果
     */
    @Override
    public boolean insertSubmissionToDB(CarbonDataSubmissionQueryParam param) {

        // 生成由项目ID和其他定长数字组成的因子代码
        String factorCode = "208" + "2" + param.getProjectId();
        // 确保因子代码长度达到10位，不足则随机填充数字
        if (factorCode.length() < 10) {
            while (factorCode.length() < 10) {
                Random random = new Random();
                int number = random.nextInt(10);
                factorCode += String.valueOf(number);
            }
        }
        // 将生成的因子代码设置到提交参数对象中
        param.setFactorCode(factorCode);
        // 使用更新后的提交参数对象，向关联的项目表中插入提交信息
        carbonProjectMapper.insertSubmissionToFactorProjectTable(param);

        // 向因子表中插入提交信息，并返回插入操作的结果
        return carbonProjectMapper.insertSubmissionToFactorTable(param);
    }


    /**
     * 根据ID获取碳汇项目信息
     * 此方法通过调用碳汇项目Mapper获取指定ID的碳汇项目信息，并通过碳方法学的字典码获取碳方法学名称
     * 如果项目不存在，则抛出业务异常
     * 还将资源文件服务中的附件列表转换后附加到返回的项目信息中
     *
     * @param id 碳汇项目的唯一标识
     * @return 包含项目详细信息的CarbonProjectQueryVo对象
     * @throws CommonBizException 当项目不存在时抛出此异常
     */
    @Override
    public CarbonProjectQueryVo getCarbonProjectById(Serializable id) {
        System.out.println("id:  "+id);
        CarbonProjectQueryVo vo = carbonProjectMapper.getCarbonProjectById(id);
        Optional.ofNullable(vo.getCarbonMethodology())
                .ifPresent(e->{
                    Optional.ofNullable(carbonMethodologyMapper.getCarbonMethodologyByDictCode(e))
                            .ifPresent(o-> vo.setCarbonMethodologyName(o.getName()==null?"":o.getName()));
        });
        if (vo == null){
            throw new CommonBizException("项目不存在");
        }
        List<CarbonResourceFile> files = carbonResourceFileService.lambdaQuery().eq(CarbonResourceFile::getFileDictCode, "023")
                .eq(CarbonResourceFile::getBusinessId, vo.getId()).list();
        vo.setAnnexList(BeanUtil.copyToList(files, CarbonProjectOwnerDataAnnex.class));
        return vo;
    }

    @Override
    public Paging<CarbonProjectListVo> getCarbonProjectPageList(CarbonProjectQueryParam param) {
        Page<?> page =getPage(param);
        page.addOrder(OrderItem.desc("cp.updated_time"));
        IPage<CarbonProjectListVo> iPage = carbonProjectMapper.getCarbonProjectPageList(page,param);
        return new Paging<>(iPage);
    }

    @Override
    public Paging<CarbonProjectListVo> getDataSubmissionPage(CarbonProjectQueryParam param) {
        Page<?> page =getPage(param);
        page.addOrder(OrderItem.desc("cp.updated_time"));
        IPage<CarbonProjectListVo> iPage = carbonProjectMapper.getDataSubmissionPage(page,param);
        return new Paging<>(iPage);
    }

    /**
     * 添加碳汇项目
     *
     * @param param 碳汇项目添加参数
     * @return 返回添加后的碳汇项目查询VO对象
     */
    @Override
    public CarbonProjectQueryVo addCarbonProject(CarbonProjectAddParam param) {
        // 日志记录入参，便于调试和排查问题
        // log.info("----> CarbonProjectAddParam: {}", JSONUtil.toJsonStr(param));

        // 将参数对象转换为碳汇项目实体对象
        CarbonProject carbonProject = BeanUtil.copyProperties(param, CarbonProject.class);
        // 设置项目状态为已提交（状态1）
        carbonProject.setProjectStatus(ProjectStatus.STATUS_1.getStatus());
        // 设置当前租户ID
        carbonProject.setTenantId(getCurrentTenantId());
        // 日志记录准备保存的碳汇项目信息
        // log.info("----> Save: carbonProject :{}", carbonProject);
        // 保存碳汇项目实体
        save(carbonProject);

        // 构建项目审批信息
        ProjectApproval approval = ProjectApproval.builder()
                // 以下为项目审批信息的构建，将碳汇项目的信息复制到审批信息中
                .projectId(carbonProject.getId())
                .legalPersonName(handleNull(carbonProject.getLegalPersonName()))
                .legalPersonPhone(handleNull(carbonProject.getLegalPersonPhone()))
                .ownerName(handleNull(carbonProject.getOwnerName()))
                .projectName(handleNull(carbonProject.getProjectName()))
                .carbonMethodology(handleNull(carbonProject.getCarbonMethodology()))
                .country(handleNull(carbonProject.getCountry()))
                .province(handleNull(carbonProject.getProvince()))
                .city(handleNull(carbonProject.getCity()))
                .address(handleNull(carbonProject.getAddress()))
                .developAgencies(handleNull(carbonProject.getAssetsDevelopAgency()))
                .principalName(handleNull(carbonProject.getPrincipalName()))
                .principalPhone(handleNull(carbonProject.getPrincipalPhone()))
                .projectIntroduction(handleNull(carbonProject.getProjectIntroduction()))
                .build();
        // 构建审批消息并同步发送到MQ，以便进行后续审批流程
        Message<ProjectApproval> msg = MessageBuilder.withPayload(approval).build();
        mqTemplate.syncSend(RocketMqName.ProjectApproval_MSG, msg, 500000, RocketDelayLevelConstant.SECOND5);

        // 构建并发送项目添加消息到MQ，以便其他系统或服务进行处理
        Message<CarbonProjectAddParam> msg2 = MessageBuilder.withPayload(param).build();
        mqTemplate.syncSend(RocketMqName.ProjectAdd_MSG, msg2, 500000, RocketDelayLevelConstant.SECOND1);

        // 返回添加后的碳汇项目信息
        return getCarbonProjectById(carbonProject.getId());
    }
    private String handleNull(String str){
        return str == null ? "-" : str;
    }

    /**
     * 更新碳汇项目信息
     *
     * @param param 碳汇项目添加参数
     * @return 更新操作是否成功
     * @throws CommonBizException 当项目不存在时抛出业务异常
     */
    @Override
    public boolean updateCarbonProject(CarbonProjectAddParam param) {
        CarbonProject carbonProject = this.getById(param.getId());
        if (carbonProject == null){
            throw new CommonBizException("项目不存在");
        }
        BeanUtil.copyProperties(param, carbonProject);

        // 更新附件资源
        ArrayList<CarbonResourceFile> files = new ArrayList<>();
        if(param.getAnnexList() != null && param.getAnnexList().size() > 0){
            for (CarbonProjectOwnerDataAnnex annex : param.getAnnexList()) {
                CarbonResourceFile file = BeanUtil.copyProperties(annex, CarbonResourceFile.class);
                file.setTenantId(getCurrentTenantId());
                file.setBusinessId(param.getId());
                file.setFileDictCode("023");
                files.add(file);
            }
        }
        carbonResourceFileService.saveBatch(files);
        return updateById(carbonProject);
    }

    /**
     * 上传业主数据
     *
     * @param param 业主数据参数
     * @throws CommonBizException 当项目不存在或更新失败时抛出业务异常
     */
    @Override
    public void uploadOwnerData(CarbonProjectOwnerDataParam param) {
        CarbonProject carbonProject = this.getById(param.getId());
        if (carbonProject == null){
            throw new CommonBizException("项目不存在");
        }
        BeanUtil.copyProperties(param, carbonProject);
        if (!updateById(carbonProject)){
            throw new CommonBizException(ExpCodeEnum.OPERATE_FAIL_ERROR);
        }

        // 保存附件资源
        ArrayList<CarbonResourceFile> files = new ArrayList<>();
        if(param.getAnnexList() != null && param.getAnnexList().size() > 0){
            for (CarbonProjectOwnerDataAnnex annex : param.getAnnexList()) {
                CarbonResourceFile file = BeanUtil.copyProperties(annex, CarbonResourceFile.class);
                file.setTenantId(getCurrentTenantId());
                file.setBusinessId(param.getId());
                file.setFileDictCode("023");
                files.add(file);
            }
        }
        carbonResourceFileService.saveBatch(files);
    }

    @Override
    public CarbonProjectContent getCarbonProjectByName(String name) {
        return carbonProjectMapper.getCarbonProjectByName(name);
    }

    @Override
    public ApiResult insertMqForm(CarbonProjectAddParam param) {
        System.out.println("param:"+param);
        return ApiResult.ok();
    }

    /**
     * 添加飞书项目
     * 将碳项目信息添加到飞书表格中指定的范围
     *
     * @param param 碳项目添加参数，包含项目相关详细信息
     * @return 返回ApiResult对象，表示操作结果
     */
    @Override
    public ApiResult addFeishuProject(CarbonProjectAddParam param) {
        // 获取碳方法学的中文名称，如果为null则默认使用"0010000000"
        String method=dictMapper.getDictCh(param.getCarbonMethodology()==null?"0010000000":param.getCarbonMethodology());
        // 获取国家的中文名称，如果为null则默认使用"0010000000"
        String country=dictMapper.getDictCh(param.getCountry()==null?"0010000000":param.getCountry());
        // 获取省份的中文名称，如果为null则默认使用"0010000000"
        String province=dictMapper.getDictCh(param.getProvince()==null?"0010000000":param.getProvince());
        // 获取城市的中文名称，如果为null则默认使用"0010000000"
        String city=dictMapper.getDictCh(param.getCity()==null?"0010000000":param.getCity());

        // 构造飞书表格API所需的JSON数据
        // 注意：此处的JSON字符串中有一些字段值为空，应该是未使用的字段或预留字段
        String json="{\"valueRange\": {\"range\": \"34372d!A1:T1\",\"values\": " +
                "[[" +
                "\""+param.getProjectName()+"\"," + // 项目名称
                "\""+""+"\"," + // 预留字段
                "\""+""+"\"," + // 预留字段
                "\""+param.getPrincipalName()+"\"," + // 负责人姓名
                "\""+param.getPrincipalPhone()+"\"," + // 负责人电话
                "\""+param.getAssetsDevelopAgency()+"\"," + // 资产开发机构
                "\""+method+"\"," + // 碳方法学中文名称
                "\""+country+"\"," + // 国家中文名称
                "\""+province+"\"," + // 省份中文名称
                "\""+city+"\"," + // 城市中文名称
                "\""+param.getAddress()+"\"," + // 地址
                "\""+param.getProjectIntroduction()+"\"," + // 项目简介
                "\""+""+"\"," + // 预留字段
                "\""+param.getOwnerName()+"\"," + // 业主姓名
                "\""+""+"\"," + // 预留字段
                "\""+""+"\"," + // 预留字段
                "\""+param.getDesignDocument()+"\"" + // 设计文件
                "]]}}";

        // 尝试使用构造的JSON数据添加项目表单
        try
        {
            ProjectAddUtil.projectFormAdd(json);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        // 返回操作成功结果
        return ApiResult.ok();
    }

}
